<?php

 /**
  * @package JooS
  * @subpackage CodeGenerator
  */

  require_once "JooS/CodeGenerator/Abstract.php";

  class JooS_CodeGenerator_Class extends JooS_CodeGenerator_Abstract {
    /**
     * @var bool
     */
    private $_final = false;

    /**
     *
     * @var bool
     */
    private $_abstract = false;

    /**
     * @var string
     */
    private $_extendedClass = null;

    /**
     * @var array
     */
    private $_properties = null;

    /**
     * @var array
     */
    private $_methods = null;

    /**
     * @param string $name
     */
    protected function __construct($name) {
      parent::__construct($name);

      $this->clearProperties();
      $this->clearMethods();
    }

    /**
     * @return string
     */
    public function compile() {
      $PHPCode = array("<?php");

      $extendedClass = $this->getExtendedClass();
      if ($extendedClass) {
        $PHPCode[] = "require_once \"" . str_replace("_", "/", $extendedClass) . ".php\";";
      }

      if ($this->isFinal()) {
        $PHPCode[] = "final";
      }

      if ($this->isAbstract()) {
        $PHPCode[] = "abstract";
      }
      
      $PHPCode[] = "class";
      $PHPCode[] = $this->getName();

      if ($extendedClass) {
        $PHPCode[] = "extends";
        $PHPCode[] = $extendedClass;
      }
      $PHPCode[] = "{";

      foreach ($this->getProperties() as $property) {
        /* @var $property JooS_CodeGenerator_Property */
        $PHPCode[] = $property->compile();
      }
      foreach ($this->getMethods() as $method) {
        /* @var $method JooS_CodeGenerator_Method */
        $PHPCode[] = $method->compile();
      }

      $PHPCode[] = "}";

      return implode(" ", $PHPCode);
    }

    /**
     * @param string $name
     * @return JooS_CodeGenerator_Class
     */
    public static function newInstance($name) {
      return new self($name);
    }

    /**
     * @param bool $final
     * @return JooS_CodeGenerator_Class
     */
    public function setFinal($final) {
      $this->_final = !!$final;

      return $this;
    }

    /**
     * @return string
     */
    public function isFinal() {
      return $this->_final;
    }

    /**
     * @return JooS_CodeGenerator_Class
     */
    public function setAbstract($abstract) {
      $this->_abstract = !!$abstract;
      return $this;
    }

    /**
     * @return bool
     */
    public function isAbstract() {
      return $this->_abstract;
    }

    /**
     * @return string
     */
    public function getExtendedClass() {
      return $this->_extendedClass;
    }

    /**
     * @param string $extendedClass
     * @return JooS_CodeGenerator_Class
     */
    public function setExtendedClass($extendedClass) {
      $this->_extendedClass = $extendedClass;
      return $this;
    }

    /**
     * @param JooS_CodeGenerator_Property $property
     * @return JooS_CodeGenerator_Class
     */
    public function addProperty(JooS_CodeGenerator_Property $property) {
      $this->_properties[] = $property;
      return $this;
    }

    /**
     * @return array
     */
    protected function getProperties() {
      return $this->_properties;
    }

    /**
     * @return JooS_CodeGenerator_Class
     */
    public function clearProperties() {
      $this->_properties = array();
      return $this;
    }

    /**
     * @param JooS_CodeGenerator_Method $method
     * @return JooS_CodeGenerator_Class
     */
    public function addMethod(JooS_CodeGenerator_Method $method) {
      $this->_methods[] = $method;
      return $this;
    }

    /**
     * @return array
     */
    protected function getMethods() {
      return $this->_methods;
    }

    /**
     * @return JooS_CodeGenerator_Class
     */
    public function clearMethods() {
      $this->_methods = array();
      return $this;
    }
  }
